import socket
import sys, os

__all__ = ["CMD_UNREGISTER", "CMD_REGISTER", "EV_WRITE", "EV_READ", "register_event", "unregister_event", "get_event"]

CMD_REGISTER = 1
CMD_UNREGISTER = 2

EV_READ = 1 << 0
EV_WRITE = 1 << 1

sys.platform = "win32"

if sys.platform == "win32":
    _pipe_address = ("127.0.0.1", 7777)
    _pipe_sockets = (
        socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0),
        socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
    )
    _pipe_sockets[0].bind(_pipe_address)


    # TODO: add code here to set socket options.
    #
    #  (cmd, fd, type)
    #

    def register_event(fd, event):
        bs = CMD_REGISTER.to_bytes(4, byteorder='big') \
             + fd.to_bytes(4, byteorder='big') \
             + event.to_bytes(4, byteorder='big')
        _pipe_sockets[1].sendto(bs, _pipe_address)


    def unregister_event(fd, event):
        bs = CMD_UNREGISTER.to_bytes(4, byteorder='big') \
             + fd.to_bytes(4, byteorder='big') \
             + event.to_bytes(4, byteorder='big')
        _pipe_sockets[1].sendto(bs, address=_pipe_address)


    def get_event():
        data, _ = _pipe_sockets[0].recvfrom(12)
        cmd, fd, event = (int.from_bytes(data[0:4], byteorder='big'),
                          int.from_bytes(data[4:8], byteorder='big'),
                          int.from_bytes(data[8:], byteorder='big'))
        return cmd, fd, event


    def get_reader_fd():
        return _pipe_sockets[0].fileno()

else:
    _pipe_fds = os.pipe()


    def register_event(fd, event):
        bs = CMD_REGISTER.to_bytes(4, byteorder='big') \
             + fd.to_bytes(4, byteorder='big') \
             + event.to_bytes(4, byteorder='big')
        os.write(_pipe_fds[1], bs)


    def unregister_event(fd, event):
        bs = CMD_UNREGISTER.to_bytes(4, byteorder='big') \
             + fd.to_bytes(4, byteorder='big') \
             + event.to_bytes(4, byteorder='big')
        os.write(_pipe_fds[1], bs)


    def get_event():
        data = os.read(_pipe_fds[0], 12)
        cmd, fd, event = (int.from_bytes(data[0:4], byteorder='big'),
                          int.from_bytes(data[4:8], byteorder='big'),
                          int.from_bytes(data[8:], byteorder='big'))
        return cmd, fd, event


    def get_reader_fd():
        return _pipe_fds[0]
